package com.ruoyi.gateway.service;

import com.ruoyi.gateway.domain.DeviceConnectionInfo;
import com.ruoyi.gateway.domain.DeviceConnectionStatus;
import com.ruoyi.gateway.domain.MessageFlowLog;
import com.ruoyi.gateway.domain.dto.*;
import com.ruoyi.gateway.mapper.DeviceConnectionStatusMapper;
import com.ruoyi.gateway.mapper.MessageFlowLogMapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.lang.management.ManagementFactory;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.atomic.AtomicLong;

@Service
@Slf4j
public class GatewayMonitorService {

    @Autowired
    private IDeviceMapService deviceMapService;

    @Autowired
    private MessageFlowLogMapper messageFlowLogMapper;

    @Autowired
    private DeviceConnectionStatusMapper connectionStatusMapper;

    // 实时连接统计
    private final AtomicInteger connectedDevices = new AtomicInteger(0);
    private final AtomicInteger connectedPlatformClients = new AtomicInteger(0);
    private final AtomicLong totalMessagesUp = new AtomicLong(0);
    private final AtomicLong totalMessagesDown = new AtomicLong(0);

    // 实时连接设备列表
    private final ConcurrentHashMap<String, DeviceConnectionInfo> connectedDeviceMap = new ConcurrentHashMap<>();
    private final ConcurrentHashMap<String, PlatformClientInfo> platformClientMap = new ConcurrentHashMap<>();

    /**
     * 记录设备连接事件
     */
    public void recordDeviceConnect(String clientId) {
        connectedDevices.incrementAndGet();

        DeviceConnectionInfo info = new DeviceConnectionInfo();
        info.setClientId(clientId);
        info.setConnectTime(new Date());
        info.setStatus(1);
        connectedDeviceMap.put(clientId, info);

        // 更新数据库状态
        updateConnectionStatus(clientId, null, 1, null);
    }

    /**
     * 记录设备断开事件
     */
    public void recordDeviceDisconnect(String clientId) {
        connectedDevices.decrementAndGet();

        DeviceConnectionInfo info = connectedDeviceMap.get(clientId);
        if (info != null) {
            info.setStatus(0);
            info.setDisconnectTime(new Date());
        }

        // 更新数据库状态
        updateConnectionStatus(clientId, null, 0, null);
    }

    /**
     * 记录平台客户端连接
     */
    public void recordPlatformClientConnect(String platformClientId, String deviceClientId) {
        connectedPlatformClients.incrementAndGet();

        PlatformClientInfo info = new PlatformClientInfo();
        info.setPlatformClientId(platformClientId);
        info.setDeviceClientId(deviceClientId);
        info.setConnectTime(new Date());
        info.setStatus(1);
        platformClientMap.put(platformClientId, info);

        // 更新数据库状态
        updateConnectionStatus(deviceClientId, platformClientId, 1, null);
    }

    /**
     * 记录平台客户端断开
     */
    public void recordPlatformClientDisconnect(String platformClientId) {
        connectedPlatformClients.decrementAndGet();

        PlatformClientInfo info = platformClientMap.get(platformClientId);
        if (info != null) {
            info.setStatus(0);
            info.setDisconnectTime(new Date());
        }

        // 更新数据库状态
        updateConnectionStatus(info.getDeviceClientId(), platformClientId, 0, null);
    }

    /**
     * 记录消息流水
     */
    public void recordMessageFlow(MessageFlowRecord record) {
        try {
            // 更新统计
            if ("up".equals(record.getDirection())) {
                totalMessagesUp.incrementAndGet();
                updateMessageCount(record.getClientClientId(), "up");
            } else {
                totalMessagesDown.incrementAndGet();
                updateMessageCount(record.getClientClientId(), "down");
            }

            // 记录到数据库
            MessageFlowLog log = new MessageFlowLog();
            log.setClientClientId(record.getClientClientId());
            log.setPlatformClientId(record.getPlatformClientId());
            log.setDirection(record.getDirection());
            log.setDeviceTopic(record.getDeviceTopic());
            log.setPlatformTopic(record.getPlatformTopic());
            log.setMessageContent(record.getMessageContent());
            log.setMessageSize(record.getMessageSize() + 0L);
            log.setStatus(record.getStatus());
            log.setErrorMessage(record.getErrorMessage());
            messageFlowLogMapper.insertMessageFlowLog(log);

            // 更新实时连接信息
            updateRealTimeMessageInfo(record);

        } catch (Exception e) {
            log.error("记录消息流水失败", e);
        }
    }

    private void updateConnectionStatus(String clientId, String platformClientId, Integer status, Date messageTime) {
        try {
            DeviceConnectionStatus statusRecord = connectionStatusMapper.selectDeviceConnectionStatusByClientId(clientId);
            if (statusRecord == null) {
                statusRecord = new DeviceConnectionStatus();
                statusRecord.setClientClientId(clientId);
                statusRecord.setPlatformClientId(platformClientId);
                statusRecord.setConnectionStatus(status + 0L);
                if (status == 1) {
                    statusRecord.setLastConnectTime(new Date());
                } else {
                    statusRecord.setLastDisconnectTime(new Date());
                }
                if (messageTime != null) {
                    statusRecord.setLastMessageTime(messageTime);
                }
                connectionStatusMapper.insertDeviceConnectionStatus(statusRecord);
            } else {
                statusRecord.setConnectionStatus(status + 0L);
                if (status == 1) {
                    statusRecord.setLastConnectTime(new Date());
                } else {
                    statusRecord.setLastDisconnectTime(new Date());
                }
                if (messageTime != null) {
                    statusRecord.setLastMessageTime(messageTime);
                }
                if (platformClientId != null) {
                    statusRecord.setPlatformClientId(platformClientId);
                }
                connectionStatusMapper.updateDeviceConnectionStatus(statusRecord);
            }
        } catch (Exception e) {
            log.error("更新连接状态失败", e);
        }
    }

    private void updateMessageCount(String clientId, String direction) {
        try {
            DeviceConnectionStatus status = connectionStatusMapper.selectDeviceConnectionStatusByClientId(clientId);
            if (status != null) {
                if ("up".equals(direction)) {
                    status.setMessageCountUp(status.getMessageCountUp() + 1);
                } else {
                    status.setMessageCountDown(status.getMessageCountDown() + 1);
                }
                status.setLastMessageTime(new Date());
                connectionStatusMapper.updateDeviceConnectionStatus(status);
            }
        } catch (Exception e) {
            log.error("更新消息计数失败", e);
        }
    }

    private void updateRealTimeMessageInfo(MessageFlowRecord record) {
        // 更新设备连接信息
        DeviceConnectionInfo deviceInfo = connectedDeviceMap.get(record.getClientClientId());
        if (deviceInfo != null) {
            if ("up".equals(record.getDirection())) {
                deviceInfo.setUpMessageCount(deviceInfo.getUpMessageCount() + 1);
            } else {
                deviceInfo.setDownMessageCount(deviceInfo.getDownMessageCount() + 1);
            }
            deviceInfo.setLastMessageTime(new Date());
        }

        // 更新平台客户端信息
        if (record.getPlatformClientId() != null) {
            PlatformClientInfo platformInfo = platformClientMap.get(record.getPlatformClientId());
            if (platformInfo != null) {
                if ("up".equals(record.getDirection())) {
                    platformInfo.setUpMessageCount(platformInfo.getUpMessageCount() + 1);
                } else {
                    platformInfo.setDownMessageCount(platformInfo.getDownMessageCount() + 1);
                }
                platformInfo.setLastMessageTime(new Date());
            }
        }
    }

    /**
     * 获取系统运行统计
     */
    public SystemStats getSystemStats() {
        SystemStats stats = new SystemStats();
        stats.setConnectedDevices(connectedDevices.get());
        stats.setConnectedPlatformClients(connectedPlatformClients.get());
        stats.setTotalMessagesUp(totalMessagesUp.get());
        stats.setTotalMessagesDown(totalMessagesDown.get());
        stats.setServerStartTime(getServerStartTime());
        stats.setCurrentTime(new Date());

        // 计算消息速率（最近1分钟）
        long oneMinuteAgo = System.currentTimeMillis() - 60000;
        stats.setMessageRateUp(calculateMessageRate(oneMinuteAgo, "up"));
        stats.setMessageRateDown(calculateMessageRate(oneMinuteAgo, "down"));

        return stats;
    }

    /**
     * 获取连接设备列表
     */
    public List<DeviceConnectionInfo> getConnectedDevices() {
        return new ArrayList<>(connectedDeviceMap.values());
    }

    /**
     * 获取平台客户端列表
     */
    public List<PlatformClientInfo> getPlatformClients() {
        return new ArrayList<>(platformClientMap.values());
    }

    /**
     * 获取消息流水记录
     */
    public List<MessageFlowLog> getRecentMessageFlow(int limit) {
        return messageFlowLogMapper.selectRecentMessages(limit);
    }

    private long calculateMessageRate(long sinceTime, String direction) {
        return messageFlowLogMapper.countMessagesSince(sinceTime, direction);
    }

    private Date getServerStartTime() {
        // 返回服务器启动时间
        return ManagementFactory.getRuntimeMXBean().getStartTime() > 0 ?
                new Date(ManagementFactory.getRuntimeMXBean().getStartTime()) : new Date();
    }
}
